package com.xxx.video.network.requests;

import android.text.TextUtils;

import com.google.gson.Gson;
import com.xxx.video.R;
import com.xxx.video.commen.utils.L;
import com.xxx.video.commen.utils.StringUtils;
import com.xxx.video.network.configs.NetWorkConstants;
import com.xxx.video.network.exceptions.NetWorkException;
import com.xxx.video.network.listeners.UploadFileListener;
import com.xxx.video.network.responses.DisposeDataHandle;

import java.io.File;
import java.util.Map;

import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;

public final class CommonRequest {
    /**
     * file type
     */
    private static final MediaType FILE_TYPE = MediaType.parse("application/octet-stream");
    /**
     * image type
     */
    private static final MediaType IMAGE_TYPE = MediaType.parse("image/png");

    /**
     * json type
     */
    private static final MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");

    private static CommonRequest mCommonRequest = null;

    private CommonRequest() {
    }

    public static CommonRequest getInstance() {
        synchronized (CommonRequest.class) {
            if (mCommonRequest == null) {
                mCommonRequest = new CommonRequest();
            }
        }
        return mCommonRequest;
    }

    /**
     * create get request
     *
     * @param requestParams request params
     * @return request
     * @throws NetWorkException exception
     */
    public Request createGetRequest(RequestParams requestParams) throws NetWorkException {
        /*
         *  if request params empty throw exception
         */
        if (requestParams == null) {
            throw new NetWorkException(NetWorkConstants.NetWorkErrorCode.REQUEST_PARAMS_EMPTY, StringUtils.getInstance().getString(R.string.net_work_request_params_empty));
        }
        /*
         * request url
         */
        String url = requestParams.getUrl();
        /*
         * if request url empty throw a exception
         */
        if (TextUtils.isEmpty(url)) {
            throw new NetWorkException(NetWorkConstants.NetWorkErrorCode.URL_EMPTY, StringUtils.getInstance().getString(R.string.net_work_request_url_empty));
        }
        /*
         *if params not empty
         */
        if (!requestParams.getParams().isEmpty()) {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(url);
            stringBuilder.append("?");
            for (Map.Entry<String, Object> entry : requestParams.getParams().entrySet()) {
                stringBuilder.append(entry.getKey());
                stringBuilder.append("=");
                stringBuilder.append(entry.getValue() == null ? "" : entry.getValue());
                stringBuilder.append("&");
            }
            /*
             * get a string
             */
            url = stringBuilder.toString();
            L.i("request url" + requestParams.getUrl(), "request params" + url);
        }
        /*
         * create header
         */
        Headers.Builder headersBuilder = new Headers.Builder();
        if (!requestParams.getHeaders().isEmpty()) {
            for (Map.Entry<String, String> entry : requestParams.getHeaders().entrySet()) {
                headersBuilder.add(entry.getKey(), entry.getValue());
            }
        }
        Request.Builder requestBuilder = new Request.Builder().url(url).headers(headersBuilder.build()).get();
        return requestBuilder.build();
    }

    /**
     * create a post form request
     *
     * @param requestParams request params
     * @return request
     * @throws NetWorkException exception
     */
    public Request createPostFormRequest(RequestParams requestParams) throws NetWorkException {
        /*
         *  if request params empty throw exception
         */
        if (requestParams == null) {
            throw new NetWorkException(NetWorkConstants.NetWorkErrorCode.REQUEST_PARAMS_EMPTY, StringUtils.getInstance().getString(R.string.net_work_request_params_empty));
        }
        /*
         * request url
         */
        String url = requestParams.getUrl();
        /*
         * if request url empty throw a exception
         */
        if (TextUtils.isEmpty(url)) {
            throw new NetWorkException(NetWorkConstants.NetWorkErrorCode.URL_EMPTY, StringUtils.getInstance().getString(R.string.net_work_request_url_empty));
        }
        /*
         * create a body
         */
        FormBody.Builder formBodyBuilder = new FormBody.Builder();
        if (!requestParams.getParams().isEmpty()) {
            for (Map.Entry<String, Object> entry : requestParams.getParams().entrySet()) {
                formBodyBuilder.add(entry.getKey(), entry.getValue() == null ? "" : (String) entry.getValue());
            }
        }
        /*
         * create a header
         */
        Headers.Builder headersBuilder = new Headers.Builder();
        if (!requestParams.getHeaders().isEmpty()) {
            for (Map.Entry<String, String> entry : requestParams.getHeaders().entrySet()) {
                headersBuilder.add(entry.getKey(), entry.getValue());
            }
        }
        Request.Builder requestBuilder = new Request.Builder().url(url).headers(headersBuilder.build()).post(formBodyBuilder.build());

        return requestBuilder.build();
    }

    /**
     * create a post json request
     *
     * @param requestParams request params
     * @return request
     * @throws NetWorkException exception
     */
    public Request createPostJsonRequest(RequestParams requestParams) throws NetWorkException {
        /*
         *  if request params empty throw exception
         */
        if (requestParams == null) {
            throw new NetWorkException(NetWorkConstants.NetWorkErrorCode.REQUEST_PARAMS_EMPTY, StringUtils.getInstance().getString(R.string.net_work_request_params_empty));
        }
        /*
         * request url
         */
        String url = requestParams.getUrl();
        /*
         * if request url empty throw a exception
         */
        if (TextUtils.isEmpty(url)) {
            throw new NetWorkException(NetWorkConstants.NetWorkErrorCode.URL_EMPTY, StringUtils.getInstance().getString(R.string.net_work_request_url_empty));
        }
        /*
         * create a body
         */
        RequestBody requestBody;
        if (requestParams.isUsedMapParams()) {
            if (requestParams.getParams() != null) {
                /*
                 * if value ==null
                 */
                if (!requestParams.getParams().isEmpty()) {
                    for (Map.Entry<String, Object> entry : requestParams.getParams().entrySet()) {
                        requestParams.getParams().put(entry.getKey(), entry.getValue() == null ? "" : entry.getValue());
                    }
                }
                String jsonParams = new Gson().toJson(requestParams.getParams());
                L.i("request url\n" + requestParams.getUrl(), "\nrequest params\n" + jsonParams + "\nrequest heade\n" + new Gson().toJson(requestParams.getHeaders()));
                requestBody = RequestBody.create(JSON_TYPE, jsonParams);
            } else {
                requestBody = RequestBody.create(JSON_TYPE, "");
            }
        } else {
            if (requestParams.getJsonObjectParams() != null) {
                String jsonParams = new Gson().toJson(requestParams.getJsonObjectParams());
                L.i("request url\n" + requestParams.getUrl(), "\nrequest params\n" + jsonParams + "\nrequest heade\n" + new Gson().toJson(requestParams.getHeaders()));
                requestBody = RequestBody.create(JSON_TYPE, jsonParams);
            } else {
                requestBody = RequestBody.create(JSON_TYPE, "");
            }
        }
        /*
         * create a header
         */
        Headers.Builder headersBuilder = new Headers.Builder();
        if (!requestParams.getHeaders().isEmpty()) {
            for (Map.Entry<String, String> entry : requestParams.getHeaders().entrySet()) {
                headersBuilder.add(entry.getKey(), entry.getValue());
            }
        }
        Request.Builder requestBuilder = new Request.Builder().url(url).headers(headersBuilder.build()).post(requestBody);
        return requestBuilder.build();
    }

    /**
     * create a upload file request
     *
     * @param requestParams     request params
     * @param disposeDataHandle response callback
     * @return request
     * @throws NetWorkException exception
     */
    public Request createMultipartRequest(RequestParams requestParams, DisposeDataHandle disposeDataHandle) throws NetWorkException {
        /*
         * if request params empty throw exception
         */
        if (requestParams == null) {
            throw new NetWorkException(NetWorkConstants.NetWorkErrorCode.REQUEST_PARAMS_EMPTY, StringUtils.getInstance().getString(R.string.net_work_request_params_empty));
        }
        /*
         * request url
         */
        String url = requestParams.getUrl();
        /*
         * if request url empty throw a exception
         */
        if (TextUtils.isEmpty(url)) {
            throw new NetWorkException(NetWorkConstants.NetWorkErrorCode.URL_EMPTY, StringUtils.getInstance().getString(R.string.net_work_request_url_empty));
        }
        /*
         * params
         */
        MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        if (!requestParams.getFileParams().isEmpty()) {
            for (Map.Entry<String, Object> entry : requestParams.getFileParams().entrySet()) {
                /*
                 * if this is a file
                 */
                if (entry.getValue() instanceof File) {
                    /*
                     * add file params
                     */
                    multipartBodyBuilder.addFormDataPart("file", entry.getKey(), RequestBody.create(FILE_TYPE, (File) entry.getValue()));
                } else if (entry.getValue() instanceof String) {
                    /*
                     * add other type params
                     */
                    multipartBodyBuilder.addFormDataPart(entry.getKey(), String.valueOf(entry.getValue()));
                }
            }
        }
        /*
         * get a head
         */
        Headers.Builder headersBuilder = new Headers.Builder();
        if (!requestParams.getHeaders().isEmpty()) {
            for (Map.Entry<String, String> entry : requestParams.getHeaders().entrySet()) {
                headersBuilder.add(entry.getKey(), entry.getValue());
            }
        }
        /*
         * is need progress
         */
        RequestBody requestBody = multipartBodyBuilder.build();
        if (disposeDataHandle != null && disposeDataHandle.mCommonResponseListener != null && disposeDataHandle.mCommonResponseListener instanceof UploadFileListener) {
            requestBody = new MultipartRequestBody(multipartBodyBuilder.build(), disposeDataHandle.mCommonResponseListener);
        }
        Request.Builder requestBuilder = new Request.Builder().url(url).headers(headersBuilder.build()).post(requestBody);
        return requestBuilder.build();
    }
}
